/*
 * main.cpp
 *
 *  Created on: 2009-8-25
 *      Author: fanliangliang
 */

#include "xscanner.h"
#include "nfa.h"

#include <iostream>

using namespace toxic;
using namespace std;

#if 0

static void print(const ScanState& t) {
	if (t.error()) {
		cout << "error" << endl;
	}
	else if (t.accept()) {
		cout << "accept" << endl;
	}
	else {
		cout << t.state() << ", " << t.advance() << ", " << t.accept() << endl;
	}
}

static void test_static_table() {
	foreach (const CharSequence& ts, token_sequences) {
		cout << ts.type << "->" << (ts.sequence == 0 ? "" : ts.sequence) << endl;
	}

	cout << "*****************************" << endl;

	//cout << STATE_TYPE_COUNT - 2 << ", " << TOKEN_TYPE_COUNT << endl;

	for (int i = 0; i < STATE_TYPE_COUNT - 2; ++i) {
		for (int j = 0; j < TOKEN_TYPE_COUNT; ++j) {
			print(transforms[i][j]);
		}
	}
}


static void test_xscanner() {
	Scanner scanner("   (20 + 36.889) - 235 / 59.7802 * ( 10000 -   528)   ");
	while (scanner.hasNext()) {
		Token token = scanner.next();
		if (token.type == TOKEN_ERROR) {
			break;
		}
		if (token.type != TOKEN_WHITESPACE) {
			cout << token.type << '[' << token.value << ']' << endl;
		}
	}
}


static void test_exprInfixToPostfix() {
	string postfix;
	bool result = exprInfixToPostfix(postfix, "3 + 4 * 2 / (1 - 5) ^ 2 ^ 3");
	//(+|-)?[0-9]+(.[0-9]+)?(E(+|-)?[0-9]+)?
	cout << result << '[' << postfix << ']' << endl;
}

static void test_regexInfixToPostfix() {
	string postfix;
	bool result = regexInfixToPostfix("(xy|z)ab|c*d+(e|fg)?(hi(jk)+)?", postfix);
	cout << result << '[' << postfix << ']' << endl;
}

#endif

static void test_regexToNfa() {
	try {
		Nfa* nfa = regexToNfa("(xy|z)ab|c*d+(e|fg)?(hi(jk)+)?");
		nfa->print();
		nfa->printEpsilonClosure();
		delete nfa;
	}
	catch (const std::exception& e) {
		xfatal << e.what();
	}
}

/*
 * Regular expression:
 *
 * 1.basic: a
 * 2.choice: a | b
 * 3.contatenation: ab
 * 4.repetition: a*
 * 5.one or more repetition: a+
 * 6.any: .
 * 7.range: [a-z0-9]
 * 8.any char not in set: [^abc]
 * 9.optional: a?
 * 0.parentheses: (a)
*/

int main() {

	xlog.setLevel(LEVEL_TRACE);
	xlog.addAppender(cout);

	//test_xscanner();
	//test_exprInfixToPostfix();
	//test_regexInfixToPostfix();
	test_regexToNfa();

	xlog.close();
	return 0;
}

